package com.macro.mall.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.macro.mall.mapper.PmProdStockIoRecordMapper;
import com.macro.mall.mapper.PmProdStockMapper;
import com.macro.mall.mapper.PmProdStockTempMapper;
import com.macro.mall.mapper.SqlCommonMapper;
import com.macro.mall.model.PmProdStock;
import com.macro.mall.model.PmProdStockIoRecord;
import com.macro.mall.model.PmProdStockIoRecordExample;
import com.macro.mall.product.dto.PmStockDoorSql;
import com.macro.mall.product.dto.QueryStockDoorDto;
import com.macro.mall.service.PmProdStockService;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class PmProdStockServiceImpl implements PmProdStockService {
    @Autowired
    private PmProdStockTempMapper pmProdStockTempMapper;
    @Autowired
    private PmProdStockMapper pmProdStockMapper;

    @Autowired
    private PmProdStockIoRecordMapper pmProdStockIoRecordMapper;
    @Autowired
    private SqlCommonMapper sqlCommonMapper;

    /**
     *  出入库类型  0 入库  1 出库  2 增加库存   11.销售扣减 12 销售回退
     */
    public static final int STOCK_IO_TYPE_DEDUCT=11;
    public static final int STOCK_IO_TYPE_ROLLBACK=12;

    /**
     * 扣减库存
     * @param changeStock
     * @return
     */
    public PmProdStock deductStock(Long stockId,Float changeStock,String orderId) throws Exception{

        PmProdStock stockDB  = pmProdStockMapper.selectByPrimaryKey(stockId);
        if(stockDB == null){
            throw new Exception("扣减库存失败，暂无库存记录");
        }

        //流水表
        PmProdStockIoRecord stockIoRecord = this.converStockIoRecord(stockDB,changeStock * -1,STOCK_IO_TYPE_DEDUCT, orderId);

        int stockCount=pmProdStockMapper.deductStockByPrimaryKey(stockDB.getId(),changeStock);
        if(stockCount == 0 ){
            throw new Exception("扣减库存失败！无更新记录");
        }else{
            pmProdStockIoRecordMapper.insert(stockIoRecord);
        }

        return stockDB;
    }

    /**
     * 回退库存
     * @param changeStock
     * @return
     */
    public boolean rollbackStock(Long prodId, Long skuInstId, Integer siteId,String stockDate,String stockTime,Float changeStock,String orderId) throws Exception{

        PmProdStock record = new PmProdStock();
        record.setProdId(prodId);
        record.setSkuInstId(skuInstId);
        record.setDealershipId(Long.valueOf(siteId));
        record.setStockDate(stockDate);
        record.setStockTime(stockTime);

        List<PmProdStock> stockList = pmProdStockMapper.selectByPmProdStock(record);
        if(stockList == null || stockList.size()>1){
            throw new Exception("回退库存失败，暂无库存记录");
        }
        PmProdStock stockDB = stockList.get(0);

        PmProdStockIoRecordExample stockIoRecordExample  = new PmProdStockIoRecordExample();
        PmProdStockIoRecordExample.Criteria stockIoRecordCriteria = stockIoRecordExample.createCriteria();
        stockIoRecordCriteria.andProdIdEqualTo(prodId);
        stockIoRecordCriteria.andSkuInstIdEqualTo(skuInstId);
        stockIoRecordCriteria.andDealershipIdEqualTo(Long.valueOf(siteId));
        stockIoRecordCriteria.andStockDateEqualTo(stockDate);
        stockIoRecordCriteria.andStockTimeEqualTo(stockTime);
        stockIoRecordCriteria.andOrderIdEqualTo(orderId);
        stockIoRecordCriteria.andTypeEqualTo(STOCK_IO_TYPE_DEDUCT);
        List<PmProdStockIoRecord>  prodStockIoRecordList =  pmProdStockIoRecordMapper.selectByExample(stockIoRecordExample);

        PmProdStockIoRecord  stockIoRecord;
        if(prodStockIoRecordList!=null && prodStockIoRecordList.size()>0){
            PmProdStockIoRecord  stockIoRecordDB = prodStockIoRecordList.get(0);
            stockIoRecord = this.converStockIoRecord(stockDB,stockIoRecordDB.getIoAmount() * -1,STOCK_IO_TYPE_ROLLBACK, orderId);
        }else{
            throw new Exception("回退库存失败，无扣减记录");
        }

        int stockCount=pmProdStockMapper.rollbackStockByPrimaryKey(stockDB.getId(),changeStock);
        if(stockCount == 0 ){
            throw new Exception("回退库存失败！无更新记录");
        }else{
            pmProdStockIoRecordMapper.insert(stockIoRecord);
        }

        return true;
    }
    private PmProdStockIoRecord converStockIoRecord(PmProdStock stock,Float changeStock,int stockIoType,String orderId){

        Date curDate = new Date();
        PmProdStockIoRecord stockIoRecord = new PmProdStockIoRecord();
        //流水表
        stockIoRecord.setChannelId(stock.getChannelId());
        stockIoRecord.setChannelName(stock.getChannelName());
        stockIoRecord.setDealershipId(stock.getDealershipId());
        stockIoRecord.setDealershipName(stock.getDealershipName());
        stockIoRecord.setProdId(stock.getProdId());
        stockIoRecord.setProdCode(stock.getProdCode());
        stockIoRecord.setProdName(stock.getProdName());

        stockIoRecord.setSkuInstId(stock.getSkuInstId());
        stockIoRecord.setSkuCode(stock.getSkuCode());
        stockIoRecord.setSkuName(stock.getSkuName());
        stockIoRecord.setType(stock.getType());
        stockIoRecord.setStockDate(stock.getStockDate());
        stockIoRecord.setStockTime(stock.getStockTime());
        stockIoRecord.setIoAmount(changeStock);
        stockIoRecord.setUnit(stock.getUnit());

        stockIoRecord.setCreateTime(curDate);
        stockIoRecord.setIoType(stockIoType);
        stockIoRecord.setOrderId(orderId);

        stockIoRecord.setStockId(stock.getId());

        return stockIoRecord;
    }
    /**
     * 回退库存
     * @param
     * @return
     */
    public boolean rollbackStockSimplify(String orderId) throws Exception{
        PmProdStock stockDB = null;

        PmProdStockIoRecordExample stockIoRecordExample  = new PmProdStockIoRecordExample();
        PmProdStockIoRecordExample.Criteria stockIoRecordCriteria = stockIoRecordExample.createCriteria();
        stockIoRecordCriteria.andOrderIdEqualTo(orderId);
        stockIoRecordCriteria.andIoTypeEqualTo(STOCK_IO_TYPE_DEDUCT);
        List<PmProdStockIoRecord>  prodStockIoRecordList =  pmProdStockIoRecordMapper.selectByExample(stockIoRecordExample);

        PmProdStockIoRecord  stockIoRecord=null;
        PmProdStockIoRecord  stockIoRecordDB;

        if(prodStockIoRecordList ==null || prodStockIoRecordList.size()==0) {
            throw new Exception("回退库存失败，无扣减记录");
        }
//            stockIoRecordDB = prodStockIoRecordList.get(0);
//
//            PmProdStock record = new PmProdStock();
//            record.setProdId(stockIoRecordDB.getProdId());
//            record.setSkuInstId(stockIoRecordDB.getSkuInstId());
//            record.setDealershipId(stockIoRecordDB.getDealershipId());
//            record.setStockDate(stockIoRecordDB.getStockDate());
//            record.setStockTime(stockIoRecordDB.getStockTime());
//
//            List<PmProdStock> stockList = pmProdStockMapper.selectByPmProdStock(record);
//            if(stockList == null || stockList.size()>1){
//                throw new Exception("回退库存失败，暂无库存记录");
//            }
//            stockDB = stockList.get(0);


        for(int m=0;m<prodStockIoRecordList.size();m++) {
            stockIoRecordDB = prodStockIoRecordList.get(m);
            stockDB = pmProdStockMapper.selectByPrimaryKey(stockIoRecordDB.getStockId());
            stockIoRecord = this.converStockIoRecord(stockDB, stockIoRecordDB.getIoAmount() * -1, STOCK_IO_TYPE_ROLLBACK, orderId);
            int stockCount=pmProdStockMapper.rollbackStockByPrimaryKey(stockDB.getId(),stockIoRecordDB.getIoAmount());
            if(stockCount == 0 ){
                throw new Exception("回退库存失败！无更新记录 stockId="+stockDB.getId()+" amount == "+stockIoRecordDB.getIoAmount());
            }else{
                pmProdStockIoRecordMapper.insert(stockIoRecord);
            }
        }

        return true;
    }
    /**
     * 上门服务扣减库存
     * @param changeStock
     * @return
     */
    public PmProdStock deductStockByDoor(QueryStockDoorDto stockDoorDto, String stockDate, String stockTime, Float changeStock, String orderId) throws Exception {

        log.info("deductStockByDoor    param :   stockDate>>>"+stockDate+"<<<stockTime>>>"+stockTime+"<<<changeStock>>>"+changeStock+"<<<changeStock>>>"+changeStock+"<<<orderId>>>"+orderId+"<<<orderId>>>"+stockTime);
        PmProdStock prodStockDB =null;

        JSONArray salePrptyArray = new JSONArray();
        JSONArray naturePrptyArray = new JSONArray();
        if (!StringUtils.isBlank(stockDoorDto.getSalePrptyArray())) {
            salePrptyArray = JSONObject.parseArray(stockDoorDto.getSalePrptyArray());
            log.info("deductStockByDoor    param :salePrptyArray >>>>"+salePrptyArray.toJSONString() );
        }
        if (!StringUtils.isBlank(stockDoorDto.getNaturePrptyArray())){
            naturePrptyArray = JSONObject.parseArray(stockDoorDto.getNaturePrptyArray());
            log.info("deductStockByDoor    param :naturePrptyArray >>>>"+naturePrptyArray.toJSONString() );
        }
        Map<String, String> paramMap = new HashMap<String, String>();
        String sql =PmStockDoorSql.getStockSqlByDoor(salePrptyArray,naturePrptyArray,stockDoorDto.getProdSpecId(),stockDoorDto.getProvCode(),stockDoorDto.getCityCode(),stockDoorDto.getCountyCode(),stockDate,stockTime);
        log.info("按规则扣减库存 sql="+sql);
        paramMap.put("sql", sql);
        List<Map<String, Object>> resultList = sqlCommonMapper.executeBySql(paramMap);

        try{
            if(resultList!=null && resultList.size()>0){
                prodStockDB=this.deductStock(Long.valueOf(resultList.get(0).get("id").toString()),changeStock,orderId);
            }else{
                paramMap = new HashMap<String, String>();
                sql =PmStockDoorSql.getStockSqlByDoorNoRule(salePrptyArray,naturePrptyArray,stockDoorDto.getProdSpecId(),stockDoorDto.getProvCode(),stockDoorDto.getCityCode(),stockDoorDto.getCountyCode(),stockDate,stockTime);
                log.info("按无规则扣减库存 sql="+sql);
                paramMap.put("sql",sql);
                 resultList = sqlCommonMapper.executeBySql(paramMap);
                if(resultList!=null && resultList.size()>0){
                    prodStockDB= this.deductStock(Long.valueOf(resultList.get(0).get("id").toString()),changeStock,orderId);
                }else {
                    throw new Exception("订单提交失败:扣减库存失败,库存为空！");
                }
            }
        }catch (Exception e){
            throw new Exception("订单提交失败:扣减库存失败！");
        }

        return prodStockDB;
    }
}
